package com.common.server.modules.file.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.common.server.common.exception.CustomerException;
import com.common.server.common.response.ResponseVo;
import com.common.server.common.util.FileType;
import com.common.server.common.util.StringUtils;
import com.common.server.modules.file.entity.FileEntity;
import com.common.server.modules.file.service.FileService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.List;
import java.util.Objects;

/**
 * <p>
 * 文件信息表 前端控制器
 * </p>
 * <p>
 * 作者: ostrich
 * 时间: 2019-10-08
 */
@Api(tags = "文件")
@RestController
@RequestMapping("api/rest/file")
public class FileController {
    private final Logger logger = LoggerFactory.getLogger(FileController.class);

    @Autowired
    public FileService iFileService;

    @ApiOperation("无分页查询数据")
    @GetMapping(value = "/list")
    public ResponseVo getList(FileEntity fileEntity) {
        try {
            QueryWrapper<FileEntity> query = Wrappers.query();
            query.in( "code", fileEntity.getCode());
            List<FileEntity> result = iFileService.list(query);
            return ResponseVo.ok(result);
        } catch (Exception e) {
            logger.error("fileList -=- {}", e.toString());
            return ResponseVo.error(e.getMessage());
        }
    }

    @ApiOperation("分页查询数据")
    @GetMapping("/list/page")
    public ResponseVo getFileList(FileEntity fileEntity) {
        try {
            Page<FileEntity> page = new Page<>();
            QueryWrapper<FileEntity> queryWrapper = new QueryWrapper<>(fileEntity);
            IPage<FileEntity> result = iFileService.page(page, queryWrapper);
            return ResponseVo.ok(result);
        } catch (Exception e) {
            logger.error("getFileList -=- {}", e.toString());
            return ResponseVo.error(e.getMessage());
        }
    }

    @ApiOperation("修改数据")
    @PostMapping(value = "/save")
    public ResponseVo fileSave(FileEntity fileEntity) {
        int count = 0;
        try {
            count = iFileService.save(fileEntity) ? 1 : 0;
        } catch (Exception e) {
            logger.error("fileUpdate -=- {}", e.toString());
        }
        return ResponseVo.ok(count);
    }

    @ApiOperation("根据id删除对象")
    @DeleteMapping(value = "/del/{id}")
    public ResponseVo fileDelete(@PathVariable String id) {
        int count = 0;
        try {
            count = iFileService.removeById(id) ? 1 : 0;
        } catch (Exception e) {
            logger.error("fileDelete -=- {}", e.toString());
        }
        return ResponseVo.ok(count);
    }

    @ApiOperation("批量删除对象")
    @DeleteMapping(value = "/del/batch")
    public ResponseVo deleteBatchIds(@RequestParam List<Long> ids) {
        int count = 0;
        try {
            count = iFileService.removeByIds(ids) ? 1 : 0;
        } catch (Exception e) {
            logger.error("fileBatchDelete -=- {}", e.toString());
        }
        return ResponseVo.ok(count);
    }

    @ApiOperation("单文件上传")
    @PostMapping("/upload")
    @ResponseBody
    public ResponseVo uploadFile(@RequestParam("file") MultipartFile file, FileEntity fileEntity,
                                 @RequestParam(name = "path", defaultValue = "temp") String path) {
        if (file.isEmpty()) {
            return ResponseVo.error("文件为空");
        }
        return iFileService.save(file, path, fileEntity);
    }

   /*
   下面的一种方式也可以实现
   @ApiOperation("根据code下载文件(可通过 name 指定下载文件名称)")
    @GetMapping("/download/{fileCode}")
    public void findFileByFileCode(@PathVariable String fileCode, HttpServletRequest request, HttpServletResponse response) {
        FileEntity fileEntity = new FileEntity();
        fileEntity.setCode(fileCode);
        FileEntity fileInfo = iFileService.getOne(new QueryWrapper<>(fileEntity));

        if (Objects.isNull(fileInfo)) {
            throw new CustomerException("文件失效或未找到文件");
        }
        String fileName = fileInfo.getName();
        String fileUrl = fileInfo.getUrl();
        File file = new File(fileUrl + fileName);

        if (!file.exists()) {
            throw new CustomerException("文件失效或未找到文件");
        }
        try {
            //解决下载时中文名称乱码
            response.reset();
            response.setCharacterEncoding("UTF-8");
            response.setContentType("application/octet-stream");
            String encodeFileName = FileType.encodeFileName(request, fileInfo.getOldName());
            response.setHeader("Content-Disposition", "attachment;fileName=" + encodeFileName);
            FileUtil.downloadFile(file, response);
            logger.info("文件[{}]下载成功", encodeFileName);
        } catch (UnsupportedEncodingException e) {
            logger.error("文件[{}]解编码失败！！！下载失败", fileName, e);
            throw new CustomerException("解编码失败");
        } catch (IOException e) {
            logger.error("文件[{}]下载失败", fileName, e);
            throw new CustomerException("文件下载失败");
        }
    }*/

    @ApiOperation("根据code下载文件(可通过 name 指定下载文件名称)")
    @GetMapping("/download/{fileCode}")
    public ResponseEntity<byte[]> findFileByFileCode(@PathVariable String fileCode, HttpServletRequest request) {

        FileEntity fileEntity = new FileEntity();
        fileEntity.setCode(fileCode);
        FileEntity fileInfo = iFileService.getOne(new QueryWrapper<>(fileEntity));

        if (Objects.isNull(fileInfo)) {
            throw new CustomerException("文件失效或未找到文件");
        }
        String fileName = fileInfo.getName();
        String fileUrl = fileInfo.getUrl();
        File file = new File(fileUrl + fileName);

        ResponseEntity<byte[]> result = null;
        FileInputStream fileInputStream = null;
        try {
            String name = StringUtils.isEmpty(fileInfo.getOldName()) ? fileInfo.getName() : fileInfo.getOldName();
            String encodeFileName = FileType.encodeFileName(request, name);
            fileInputStream = new FileInputStream(file);
            byte[] b = new byte[fileInputStream.available()];
            fileInputStream.read(b);
            HttpHeaders headers = new HttpHeaders();
//            headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_OCTET_STREAM_VALUE);
            headers.add(HttpHeaders.CONNECTION, "close");
            headers.add(HttpHeaders.ACCEPT_RANGES, "bytes");
            headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + encodeFileName);
            headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
            result = new ResponseEntity<>(b, headers, HttpStatus.OK);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fileInputStream != null) {
                try {
                    fileInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return result;
    }

    @ApiOperation("word 转换为 html")
    @PostMapping("/word2Html")
    public ResponseVo parseDocToHtml(@RequestParam("file") MultipartFile file, @RequestParam("url") String url) {
        if (file.isEmpty()) {
            return ResponseVo.error("文件为空");
        }
        return ResponseVo.ok().put("data", iFileService.word2html(file, url));
    }
}

